home *** CD-ROM | disk | FTP | other *** search
/ Programming an RTS Game with Direct3D / Programming an RTS Game with Direct3D.iso / Examples / Chapter 15 / Example 15.2 / app.cpp next >
Encoding:
C/C++ Source or Header  |  2006-08-14  |  7.3 KB  |  305 lines

  1. #include "app.h"
  2.  
  3. APPLICATION app;
  4.  
  5. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE prevInstance, PSTR cmdLine, int showCmd)
  6. {    
  7.     if(FAILED(app.Init(hInstance, 800, 600, true)))
  8.         return 0;
  9.  
  10.     MSG msg;
  11.     memset(&msg, 0, sizeof(MSG));
  12.     int startTime = timeGetTime(); 
  13.  
  14.     while(msg.message != WM_QUIT)
  15.     {
  16.         try
  17.         {
  18.             if(::PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
  19.             {
  20.                 ::TranslateMessage(&msg);
  21.                 ::DispatchMessage(&msg);
  22.             }
  23.             else
  24.             {    
  25.                 int t = timeGetTime();
  26.                 float deltaTime = (t - startTime)*0.001f;
  27.  
  28.                 app.Update(deltaTime);
  29.                 app.Render();
  30.  
  31.                 startTime = t;
  32.             }
  33.         }
  34.         catch(...){}
  35.     }
  36.  
  37.     app.Cleanup();
  38.  
  39.     return msg.wParam;
  40. }
  41.  
  42. APPLICATION::APPLICATION()
  43. {
  44.     m_pDevice = NULL; 
  45.     m_mainWindow = 0;
  46.     srand(GetTickCount());
  47. }
  48.  
  49. HRESULT APPLICATION::Init(HINSTANCE hInstance, int width, int height, bool windowed)
  50. {
  51.     debug.Print("Application initiated");
  52.  
  53.     //Create Window Class
  54.     WNDCLASS wc;
  55.     memset(&wc, 0, sizeof(WNDCLASS));
  56.     wc.style         = CS_HREDRAW | CS_VREDRAW;
  57.     wc.lpfnWndProc   = (WNDPROC)::DefWindowProc; 
  58.     wc.hInstance     = hInstance;
  59.     wc.lpszClassName = "D3DWND";
  60.  
  61.     //Register Class and Create new Window
  62.     RegisterClass(&wc);
  63.     m_mainWindow = CreateWindow("D3DWND", "Example 15.2: RTS Network Framework", WS_EX_TOPMOST, 0, 0, width, height, 0, 0, hInstance, 0); 
  64.     SetCursor(NULL);
  65.     ShowWindow(m_mainWindow, SW_SHOW);
  66.     UpdateWindow(m_mainWindow);
  67.  
  68.     //Create IDirect3D9 Interface
  69.     IDirect3D9* d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
  70.  
  71.     if(d3d9 == NULL)
  72.     {
  73.         debug.Print("Direct3DCreate9() - FAILED");
  74.         return E_FAIL;
  75.     }
  76.  
  77.     //Check that the Device supports what we need from it
  78.     D3DCAPS9 caps;
  79.     d3d9->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &caps);
  80.  
  81.     //Hardware Vertex Processing or not?
  82.     int vp = 0;
  83.     if(caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT)
  84.         vp = D3DCREATE_HARDWARE_VERTEXPROCESSING;
  85.     else vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
  86.  
  87.     //Check vertex & pixelshader versions
  88.     if(caps.VertexShaderVersion < D3DVS_VERSION(2, 0) || caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
  89.     {
  90.         debug.Print("Warning - Your graphic card does not support vertex and pixelshaders version 2.0");
  91.     }
  92.  
  93.     //Set D3DPRESENT_PARAMETERS
  94.     D3DPRESENT_PARAMETERS d3dpp;
  95.     d3dpp.BackBufferWidth            = width;
  96.     d3dpp.BackBufferHeight           = height;
  97.     d3dpp.BackBufferFormat           = D3DFMT_A8R8G8B8;
  98.     d3dpp.BackBufferCount            = 1;
  99.     d3dpp.MultiSampleType            = D3DMULTISAMPLE_NONE;
  100.     d3dpp.MultiSampleQuality         = 0;
  101.     d3dpp.SwapEffect                 = D3DSWAPEFFECT_DISCARD; 
  102.     d3dpp.hDeviceWindow              = m_mainWindow;
  103.     d3dpp.Windowed                   = windowed;
  104.     d3dpp.EnableAutoDepthStencil     = true; 
  105.     d3dpp.AutoDepthStencilFormat     = D3DFMT_D24S8;
  106.     d3dpp.Flags                      = 0;
  107.     d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
  108.     d3dpp.PresentationInterval       = D3DPRESENT_INTERVAL_IMMEDIATE;
  109.  
  110.     //Create the IDirect3DDevice9
  111.     if(FAILED(d3d9->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, m_mainWindow,
  112.                                  vp, &d3dpp, &m_pDevice)))
  113.     {
  114.         debug.Print("Failed to create IDirect3DDevice9");
  115.         return E_FAIL;
  116.     }
  117.  
  118.     //Release IDirect3D9 interface
  119.     d3d9->Release();
  120.  
  121.     LoadObjectResources(m_pDevice);
  122.     LoadMapObjectResources(m_pDevice);
  123.     LoadUnitResources(m_pDevice);
  124.     LoadBuildingResources(m_pDevice);
  125.     LoadPlayerResources(m_pDevice);
  126.  
  127.     m_thisPlayer = 0;
  128.     m_terrain.Init(m_pDevice, INTPOINT(150, 150));
  129.     m_camera.Init(m_pDevice);
  130.     m_camera.m_focus = m_terrain.GetWorldPos(INTPOINT(75,75));
  131.  
  132.     m_mouse.InitMouse(m_pDevice, m_mainWindow);
  133.     m_lobby.Init(m_pDevice);
  134.  
  135.     //Set sampler state
  136.     for(int i=0;i<8;i++)
  137.     {
  138.         m_pDevice->SetSamplerState(i, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
  139.         m_pDevice->SetSamplerState(i, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
  140.         m_pDevice->SetSamplerState(i, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
  141.     }
  142.  
  143.     return S_OK;
  144. }
  145.  
  146. HRESULT APPLICATION::Update(float deltaTime)
  147. {        
  148.     try
  149.     {
  150.         //Control camera
  151.         m_mouse.Update(&m_terrain);
  152.  
  153.         if(!m_lobby.Done())
  154.             m_lobby.Update(deltaTime, m_mouse);
  155.         else
  156.         {
  157.             m_camera.Update(m_mouse, m_terrain, deltaTime);
  158.  
  159.             //Update Players
  160.             for(int i=0;i<m_players.size();i++)
  161.                 if(m_players[i] != NULL)
  162.                     m_players[i]->UpdateMapObjects(deltaTime);
  163.  
  164.             //Order units of team 0 around...
  165.             if(m_thisPlayer < m_players.size() && m_players[m_thisPlayer] != NULL)
  166.                 m_players[m_thisPlayer]->UnitOrders(m_mouse);
  167.         }
  168.  
  169.         //Keyboard input
  170.         if(KEYDOWN('W'))
  171.         {
  172.         }
  173.         else if(KEYDOWN(VK_ESCAPE))
  174.         {
  175.             Quit();
  176.         }
  177.     }
  178.     catch(...){}
  179.  
  180.     return S_OK;
  181. }    
  182.  
  183. HRESULT APPLICATION::Render()
  184. {
  185.     try
  186.     {
  187.         // Clear the viewport
  188.         m_pDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
  189.  
  190.         // Begin the scene 
  191.         if(SUCCEEDED(m_pDevice->BeginScene()))
  192.         {
  193.             if(!m_lobby.Done())
  194.                 m_lobby.Draw(m_mouse);
  195.             else
  196.             {
  197.                 m_terrain.Render(m_camera);
  198.  
  199.                 for(int i=0;i<m_players.size();i++)
  200.                     if(m_players[i] != NULL)
  201.                         m_players[i]->RenderMapObjects(m_camera);
  202.  
  203.                 //Select units
  204.                 if(m_thisPlayer < m_players.size() && m_players[m_thisPlayer] != NULL)
  205.                 {
  206.                     m_players[m_thisPlayer]->PaintSelectedMapObjects(m_camera);
  207.                     m_players[m_thisPlayer]->Select(m_mouse);
  208.                 }
  209.             }
  210.  
  211.             m_mouse.Paint();
  212.  
  213.             // End the scene.
  214.             m_pDevice->EndScene();
  215.             m_pDevice->Present(0, 0, 0, 0);
  216.         }
  217.     }
  218.     catch(...){}
  219.  
  220.     return S_OK;
  221. }
  222.  
  223. HRESULT APPLICATION::Cleanup()
  224. {
  225.     try
  226.     {
  227.         m_terrain.Release();
  228.  
  229.         UnloadObjectResources();
  230.         UnloadMapObjectResources();
  231.         UnloadUnitResources();
  232.         UnloadBuildingResources();
  233.         UnloadPlayerResources();
  234.  
  235.         for(int i=0;i<m_players.size();i++)
  236.             if(m_players[i] != NULL)
  237.                 delete m_players[i];
  238.         m_players.clear();
  239.  
  240.         m_pDevice->Release();
  241.  
  242.         debug.Print("Application terminated");
  243.     }
  244.     catch(...){}
  245.     
  246.     return S_OK;
  247. }
  248.  
  249. HRESULT APPLICATION::Quit()
  250. {
  251.     try
  252.     {
  253.         ::DestroyWindow(m_mainWindow);
  254.         ::PostQuitMessage(0);
  255.     }
  256.     catch(...){}
  257.  
  258.     return S_OK;
  259. }
  260.  
  261. void APPLICATION::AddPlayers(int num, int activePlayer)
  262. {
  263.     srand(num);
  264.  
  265.     m_thisPlayer = activePlayer;
  266.  
  267.     for(int i=0;i<m_players.size();i++)
  268.         if(m_players[i] != NULL)
  269.             delete m_players[i];
  270.     m_players.clear();
  271.  
  272.     INTPOINT startLocations[] = {INTPOINT(30,30), INTPOINT(120,30), INTPOINT(30,120), INTPOINT(120,120)};
  273.     D3DXVECTOR4 teamCols[] = {D3DXVECTOR4(1.0f, 0.0f, 0.0f, 1.0f), D3DXVECTOR4(0.0f, 1.0f, 0.0f, 1.0f),
  274.                               D3DXVECTOR4(0.0f, 0.0f, 1.0f, 1.0f), D3DXVECTOR4(1.0f, 1.0f, 0.0f, 1.0f)};
  275.     
  276.     if(num < 2)num = 2;
  277.     if(num > 4)num = 4;
  278.  
  279.     for(int i=0;i<num;i++)
  280.     {
  281.         m_terrain.Progress("Creating Players", i / (float)num);
  282.         m_players.push_back(new PLAYER(i, teamCols[i], startLocations[i], &m_terrain, m_pDevice));    
  283.     }
  284.  
  285.     //Center camera focus on the team...
  286.     m_camera.m_focus = m_terrain.GetWorldPos(m_players[m_thisPlayer]->GetCenter());
  287. }
  288.  
  289. void APPLICATION::HandleNetworkOrder(RTS_MSG *msg)
  290. {
  291.     if(msg == NULL)return;    
  292.  
  293.     if(msg->type == GAME_MSG_ORDER)
  294.     {
  295.         MSG_ORDER *order = (MSG_ORDER*)msg;
  296.  
  297.         if(m_terrain.Within(order->dest))
  298.             if(order->player >= 0 && order->player < m_players.size())
  299.                 if(order->unitID >= 0 && order->unitID < m_players[order->player]->m_mapObjects.size())
  300.                 {
  301.                     UNIT *unit = (UNIT*)m_players[order->player]->m_mapObjects[order->unitID];
  302.                     unit->MoveTo(order->dest, false, true);
  303.                 }
  304.     }    
  305. }